<template>
  <el-form :model="formState">
    <el-row :gutter="gutter">
      <el-col v-for="(item, index) in formItems"
              :span="colSpan||item.col">
        <el-form-item :key="item.prop"
                      :prop="item.prop"
                      :label="item.label"
                      :rules="item._rule"
                      :label-width="labelWidth">
          <el-input v-if="item.type == 'input'"
                    v-bind="item.attrs"
                    v-model="formState[item?.prop]"
                    :placeholder="`请输入${item.label}`">
          </el-input>
          <el-select v-if="item.type == 'select'"
                     v-bind="item.attrs"
                     v-model="formState[item?.prop]"
                     :placeholder="`请选择${item.label}`">
            <el-option v-for="option in item.options"
                       :label="option.label"
                       :value="option.value" />
          </el-select>
          <el-date-picker v-if="item.type == 'date-picker'"
                          v-bind="item.attrs"
                          v-model="formState[item?.prop]"
                          :placeholder="`请选择${item.label}`">
          </el-date-picker>
          <el-input-number v-if="item.type == 'input-number'"
                           v-bind="item.attrs"
                           v-model="formState[item?.prop]"
                           :placeholder="`请选择${item.label}`">
          </el-input-number>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>
<script setup>
const props = defineProps({
  formConfig: {
    type: Array,
    default: () => []
  },
  gutter: {
    type: Number,
    default: 12
  },
  labelWidth: {
    type: Object,
    default: () => ({})
  },
  colSpan: {
    type: Number,
    default: 6
  },
  formData: {
    type: Object,
    required: true
  }
})

const formState = toRef(props, 'formData')
const inputMap = ['a-input', 'a-input-number', 'a-editor', 'a-textarea']
const getRule = item => {
  const { validator, required, type, label } = item
  const isInput = inputMap.indexOf(type) > -1
  /* 配置 required: 必填 */
  if (typeof required === 'boolean' && required) {
    return [
      {
        required: true,
        message: `请${isInput ? '输入' : '选择'}${label}`,
        trigger: `${isInput ? 'blur' : 'change'}`
      }
    ]
  } else if (isFunction(validator)) {
    /* 配置 rule: 自定义校验规则待完善 */
    return [
      {
        required: true,
        validator: item.validator,
        trigger: `${isInput ? 'blur' : 'change'}`
      }
    ]
  } else {
    return item.rule
  }
}

const isShow = (item, formState) => {
  if (!isFunction(item.isShow)) {
    return true
  } else {
    return item.isShow(item, formState)
  }
}

const isFunction = fn => typeof fn === 'function'

const computeFormItem = (item, formState) => {
  return {
    ...item,
    _rule: getRule(item),
    _hide: isShow(item, formState)
  }
}

const formItems = computed(() => {
  return props.formConfig
    .map(item => computeFormItem(item, formState.value))
    .filter(item => item._hide)
})

onMounted(() => {
  console.log(formItems)
})

defineExpose({ formState })
</script>
<style lang="scss" scoped></style>
